<!DOCTYPE html>
<html>
  <head>
    <title>Test for slicing blobs that originated in a child process</title>
    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
    </script>
    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
  </head>
  <body onload="setup();">
    <script type="application/javascript;version=1.7">
"use strict";

function childFrameScript() {
  "use strict";

  Components.utils.importGlobalProperties(["Blob"]);

  const messageName = "test:blob-slice-test";
  const blobData = ["So", " ", "many", " ", "blobs!"];
  const blobText = blobData.join("");
  const blobType = "text/plain";

  let blob = new Blob(blobData, { type: blobType });

  let sliceText = blobData[2][1] + blobData[2][2];
  let sliceIndex = blobText.indexOf(sliceText);

  let firstSliceStart = blobData[0].length + blobData[1].length;
  let firstSliceEnd = firstSliceStart + blobData[2].length;

  let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);

  let secondSliceStart = blobData[2].indexOf("a");
  let secondSliceEnd = secondSliceStart + 2;

  slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);

  sendAsyncMessage(messageName, { blob: blob });
  sendAsyncMessage(messageName, { slice: slice });
}

function parentFrameScript(mm) {
  const messageName = "test:blob-slice-test";
  const blobData = ["So", " ", "many", " ", "blobs!"];
  const blobText = blobData.join("");
  const blobType = "text/plain";

  const sliceText = "an";

  let receivedBlob = false;
  let receivedSlice = false;

  let finishedTestingBlob = false;
  let finishedTestingSlice = false;

  mm.addMessageListener(messageName, function(message) {
    if ("blob" in message.data) {
      is(receivedBlob, false, "Have not yet received Blob");
      is(receivedSlice, false, "Have not yet received Slice");
      is(finishedTestingBlob, false, "Have not yet finished testing Blob");
      is(finishedTestingSlice, false, "Have not yet finished testing Slice");

      receivedBlob = true;

      let blob = message.data.blob;

      ok(blob instanceof Blob, "Received a Blob");
      is(blob.size, blobText.length, "Blob has correct size");
      is(blob.type, blobType, "Blob has correct type");

      let slice = blob.slice(blobText.length -
                                blobData[blobData.length - 1].length,
                              blob.size,
                              blobType);

      ok(slice instanceof Blob, "Slice returned a Blob");
      is(slice.size,
          blobData[blobData.length - 1].length,
          "Slice has correct size");
      is(slice.type, blobType, "Slice has correct type");

      let reader = new FileReader();
      reader.onload = function() {
        is(reader.result,
            blobData[blobData.length - 1],
            "Slice has correct data");

        finishedTestingBlob = true;

        if (finishedTestingSlice) {
          SimpleTest.finish();
        }
      };
      reader.readAsText(slice);

      return;
    }

    if ("slice" in message.data) {
      is(receivedBlob, true, "Already received Blob");
      is(receivedSlice, false, "Have not yet received Slice");
      is(finishedTestingSlice, false, "Have not yet finished testing Slice");

      receivedSlice = true;

      let slice = message.data.slice;

      ok(slice instanceof Blob, "Received a Blob for slice");
      is(slice.size, sliceText.length, "Slice has correct size");
      is(slice.type, blobType, "Slice has correct type");

      let reader = new FileReader();
      reader.onload = function() {
        is(reader.result, sliceText, "Slice has correct data");

        let slice2 = slice.slice(1, 2, blobType);

        ok(slice2 instanceof Blob, "Slice returned a Blob");
        is(slice2.size, 1, "Slice has correct size");
        is(slice2.type, blobType, "Slice has correct type");

        let reader2 = new FileReader();
        reader2.onload = function() {
          is(reader2.result, sliceText[1], "Slice has correct data");

          finishedTestingSlice = true;

          if (finishedTestingBlob) {
            SimpleTest.finish();
          }
        };
        reader2.readAsText(slice2);
      };
      reader.readAsText(slice);

      return;
    }

    ok(false, "Received a bad message: " + JSON.stringify(message.data));
  });

  mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
                      false);
}

function setup() {
  info("Got load event");

  SpecialPowers.pushPrefEnv(
    { set: [ ["dom.ipc.browser_frames.oop_by_default", true],
              ["dom.mozBrowserFramesEnabled", true],
              ["network.disable.ipc.security", true],
              ["browser.pagethumbnails.capturing_disabled", true] ] },
    function() {
      info("Prefs set");

      SpecialPowers.pushPermissions(
        [ { type: "browser", allow: true, context: document } ],
        function() {
          info("Permissions set");

          let iframe = document.createElement("iframe");
          SpecialPowers.wrap(iframe).mozbrowser = true;
          iframe.id = "iframe";
          iframe.src =
            "data:text/html,<!DOCTYPE HTML><html><body></body></html>";

          iframe.addEventListener("mozbrowserloadend", function() {
            info("Starting tests");

            let mm = SpecialPowers.getBrowserFrameMessageManager(iframe)
            parentFrameScript(mm);
          });

          document.body.appendChild(iframe);
        }
      );
    }
  );
}

SimpleTest.waitForExplicitFinish();
  </script>
  </body>
</html>
